<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>10_ES12-FinalizationRegistry</title>
  <!-- 
  在 JavaScript 的 ES12（ECMAScript 2021）中，引入了  `FinalizationRegistry` 。这个新特性允许开发者注册一个回调函数，该函数会在某个对象被垃圾回收时被调用。这对于管理内存和清理资源非常有用。
  一、定义
  `FinalizationRegistry`  是一个内置的 JavaScript 对象，它允许你注册一个回调函数，该函数会在与之关联的对象被垃圾回收时被调用。它主要用于在对象被回收后执行清理操作，比如释放资源或注销事件监听器等。

  二、构造函数
   1. 语法
  const registry = new FinalizationRegistry(callback);
  - callback：当与注册的对象关联的对象被垃圾回收时调用的函数。该函数接收一个参数，该参数是与被回收对象关联的值。

  三、使用过程
   1. 注册对象

  使用  `register()`  方法将一个对象注册到  `FinalizationRegistry`  中。

   2. 解除注册
  使用  `unregister()`  方法可以解除注册，但这并不是必须的，因为垃圾回收会在对象不再被引用时自动处理。

   3. 回调函数
  当对象被垃圾回收时，注册时提供的回调函数会被调用。

   4. 示例
  以下是一个简单的示例，展示了如何使用  `FinalizationRegistry` ：
  // 创建一个 FinalizationRegistry 实例
  const registry = new FinalizationRegistry((heldValue) => {
      console.log(`对象被垃圾回收了，heldValue: ${heldValue}`);
  });

  // 创建一个对象
  let obj = { name: '小明' };

  // 注册对象，heldValue 为与该对象关联的值
  registry.register(obj, '这是与 obj 关联的值');

  // 删除对 obj 的引用
  obj = null;

  // 触发垃圾回收（注意：垃圾回收是非确定性的，可能不会立即发生）
  在这个示例中，当  `obj`  被垃圾回收时，控制台会输出一条消息，表明对象已经被回收，并显示与之关联的值。

  四、注意事项
  1. 非确定性：垃圾回收是非确定性的，不能保证何时会发生。因此，无法控制回调函数的调用时机。
  2. 性能影响：在高频率创建和销毁对象的情况下，使用  `FinalizationRegistry`  可能会对性能产生影响。
  3. 不适合用于关键逻辑：由于回调函数的执行时机不确定，不建议在关键逻辑中依赖  `FinalizationRegistry` 。

  五、总结
  - 功能： `FinalizationRegistry`  允许开发者在对象被垃圾回收时执行清理操作，提供了一种管理内存和资源的机制。
  - 使用方法：通过  `register()`  注册对象，提供回调函数；当对象被回收时，回调函数会被调用。
  - 特性：垃圾回收是非确定性的，调用时机不可预测，适合用于非关键的清理操作。
  -->
</head>
<body>

  <script>

    let obj = { name: '小明', age: 18};
    let info = { name: '小红', age: 20};

    let registry = new FinalizationRegistry((heldValue) => {
      console.log(`对象被垃圾回收了，heldValue: ${heldValue}`)
    })

    registry.register(obj, '这是与 obj 关联的值')
    registry.register(info, '小红')
    obj = null;
    info = null

  </script>
  
</body>
</html>